package com.dukk.gis.tools.extensions.skewer.demo;


import com.dukk.gis.tools.WktTool;
import com.dukk.gis.tools.extensions.skewer.Node;
import com.dukk.gis.tools.extensions.skewer.Seeker;
import com.dukk.gis.tools.extensions.skewer.SeekerWay;
import com.dukk.gis.tools.extensions.skewer.Skewer;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.LineString;
import org.locationtech.jts.geom.MultiLineString;
import org.locationtech.jts.io.ParseException;

import java.util.*;

/**
 * 穿线,通过pid关系进行穿串
 */
public class LinkSeeker implements Seeker<Link> {

    public static List<Link> linkData = new ArrayList<>();

    static {
        try {
            Geometry g1 = WktTool.wktToGeo("LINESTRING (116.24839000000001 40.07576, 116.24845000000002 40.07580000000001)");
            Geometry g2 = WktTool.wktToGeo("LINESTRING (116.24845000000002 40.07580000000001, 116.24849000000002 40.07582000000001)");
            Geometry g3 = WktTool.wktToGeo("LINESTRING (116.24849000000002 40.07582000000001, 116.24853000000002 40.07585)");
            Geometry g4 = WktTool.wktToGeo("LINESTRING (116.24853000000002 40.07585, 116.24856000000001 40.07587000000001, 116.24859000000002 40.075880000000005, 116.24864000000002 40.075900000000004, 116.24870000000001 40.07592, 116.24873000000002 40.07593000000001)");

            Geometry g4_5 = WktTool.wktToGeo("LINESTRING (116.24873000000002 40.07593000000001,116.24873000000002 40.075950000000006, 116.24873000000002 40.07600000000001)");
            Geometry g4_6 = WktTool.wktToGeo("LINESTRING (116.24873000000002 40.07593000000001,116.24875000000002 40.07591000000001, 116.24879000000001 40.07589000000001)");

            createLink(g1, 1L, 2L, 1L);
            createLink(g2, 2L, 3L, 2L);
            createLink(g3, 3L, 4L, 3L);
            createLink(g4, 4L, 5L, 4L);

            createLink(g4_5, 5L, 6L, 5L);
            createLink(g4_6, 5L, 7L, 6L);


        } catch (ParseException e) {
            throw new RuntimeException(e);
        }

    }

    static void createLink(Geometry geometry, long startNodePid, long endNodePid, long id){
        Link link = new Link();
        link.setId(id);
        link.setStartNodeId(startNodePid);
        link.setEndNodeId(endNodePid);
        link.setLineString(geometry);

        linkData.add(link);

    }


    @Override
    public List<Node<Link>> findNode(Link parentLink, List<Link> dataList, Object message) throws Exception {

        long nextNode = (long)message;

        List<Node<Link>> nodeList = new ArrayList<>();

        if(null != dataList && dataList.size() > 0){
            for(Link currentLink : linkData){
                long sNodePid = currentLink.getStartNodeId();
                long eNodePid = currentLink.getEndNodeId();
                List<Long> nodeIdList = Arrays.asList(sNodePid, eNodePid);

                if(nodeIdList.contains(nextNode) && currentLink.getId() != parentLink.getId()){

                    Node node = new Node();
                    node.setElement(currentLink);
                    node.setId(currentLink.getId());
                    node.setGeometry(currentLink.getLineString());
                    node.setLength(currentLink.getLineString().getLength());
                    node.setStartPoint(((LineString)currentLink.getLineString()).getStartPoint());
                    node.setEndPoint(((LineString)currentLink.getLineString()).getEndPoint());

                    node.setStartNode(currentLink.getStartNodeId());
                    node.setEndNode(currentLink.getEndNodeId());

                    nodeList.add(node);
                }
            }
        }

        return nodeList;
    }

    @Override
    public boolean stopCondition(LinkedList<Node<Link>> parentLinkedList, Node<Link> currentNode) {
        return false;
    }


    public static void main(String[] args) throws Exception {

        Geometry g1 = WktTool.wktToGeo("LINESTRING (116.24839000000001 40.07576, 116.24845000000002 40.07580000000001)");

        //第一个节点对象(穿串开始节点) 外部对象
        Link link = new Link();
        link.setId(1L);
        link.setStartNodeId(1L);
        link.setEndNodeId(2L);
        link.setLineString(g1);


        //创建节点对象
        Node<Link> node  = new Node<>();
        node.setId(link.getId());
        node.setGeometry(link.getLineString());
        node.setElement(link);

        node.setLength(link.getLineString().getLength());
        node.setStartPoint(((LineString)link.getLineString()).getStartPoint());
        node.setEndPoint(((LineString)link.getLineString()).getEndPoint());

        node.setStartNode(link.getStartNodeId());
        node.setEndNode(link.getEndNodeId());

        //穿串调用
        System.out.println("穿串测试开始:");
        LinkSeeker rdLinkSeeker = new LinkSeeker();
        Skewer<Link> skewer = new Skewer<>(rdLinkSeeker, SeekerWay.POINT_END, link);
        List<LinkedList<Node<Link>>> linkedLists = skewer.searchKebab(node,LinkSeeker.linkData);

        GeometryFactory geometryFactory = new GeometryFactory();

        System.out.println("穿串测试,共计穿出["+linkedLists.size()+"]组");

        int  z=1;
        for (LinkedList<Node<Link>> linkedList : linkedLists){

            LineString[] lineStrings = new LineString[linkedList.size()];


            System.out.println("穿串测试,第["+z+"]组");
            for(int i=0; i<linkedList.size();i++){
                Node<Link> node1 = linkedList.get(i);
                lineStrings[i] = (LineString) node1.getGeometry();

                System.out.println("穿串测试,第["+z+"]组,nodeId:"+node1.getId());



            }

            MultiLineString multiLineString = geometryFactory.createMultiLineString(lineStrings);
            System.out.println(multiLineString.toText());
            System.out.println("\r\n");

            z++;
        }


    }

}
